// char_device.c
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/slab.h>

#define DEVICE_NAME "my_char_device"
#define BUFFER_SIZE 1024

static char *buffer;
static int major_number;

// 打开设备
static int my_open(struct inode *inode, struct file *file) {
    printk(KERN_INFO "Device opened\n");
    return 0;
}

// 读取设备
static ssize_t my_read(struct file *file, char __user *user_buffer, size_t count, loff_t *offset) {
    ssize_t bytes_read = 0;

    if (*offset >= BUFFER_SIZE) {
        return 0; // EOF
    }

    if (*offset + count > BUFFER_SIZE) {
        count = BUFFER_SIZE - *offset; // 限制读取的字节数
    }

    if (copy_to_user(user_buffer, buffer + *offset, count)) {
        return -EFAULT; // 发生错误
    }

    *offset += count;
    bytes_read = count;
    printk(KERN_INFO "Read %zu bytes\n", bytes_read);
    return bytes_read;
}

// 写入设备
static ssize_t my_write(struct file *file, const char __user *user_buffer, size_t count, loff_t *offset) {
    ssize_t bytes_written = 0;

    if (*offset >= BUFFER_SIZE) {
        return -ENOSPC; // 没有空间
    }

    if (*offset + count > BUFFER_SIZE) {
        count = BUFFER_SIZE - *offset; // 限制写入的字节数
    }

    if (copy_from_user(buffer + *offset, user_buffer, count)) {
        return -EFAULT; // 发生错误
    }

    *offset += count;
    bytes_written = count;
    printk(KERN_INFO "Wrote %zu bytes\n", bytes_written);
    return bytes_written;
}

// 关闭设备
static int my_close(struct inode *inode, struct file *file) {
    printk(KERN_INFO "Device closed\n");
    return 0;
}

// 文件操作结构体
static struct file_operations fops = {
    .owner = THIS_MODULE,
    .open = my_open,
    .read = my_read,
    .write = my_write,
    .release = my_close,
};

// 初始化模块
static int __init my_char_device_init(void) {
    major_number = register_chrdev(0, DEVICE_NAME, &fops);
    if (major_number < 0) {
        printk(KERN_ALERT "Failed to register character device\n");
        return major_number;
    }

    buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL);
    if (!buffer) {
        unregister_chrdev(major_number, DEVICE_NAME);
        return -ENOMEM;
    }

    memset(buffer, 0, BUFFER_SIZE); // 初始化缓冲区
    printk(KERN_INFO "Character device registered with major number %d\n", major_number);
    return 0;
}

// 卸载模块
static void __exit my_char_device_exit(void) {
    kfree(buffer); // 释放缓冲区
    unregister_chrdev(major_number, DEVICE_NAME); // 注销字符设备
    printk(KERN_INFO "Character device unregistered\n");
}

module_init(my_char_device_init);
module_exit(my_char_device_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("A simple character device driver");

/*

: 实现一个字符设备驱动，能够读取和写入数据到用户空间。要求支持基本的文件操作（open, read, write, close）。

make
sudo insmod char_device.ko

echo "Hello, World!" > /dev/my_char_device
cat /dev/my_char_device

sudo rmmod char_device

*/

